--Universidade Federal de Campina Grande
--Centro de Enegenharia Elétrica e Informática
--Unidade Acadêmica de Sistemas e Computação
--Disciplina: Paradigmas de Linguagens de Programação
--Professor: Franklin Ramalho
--Equipe: Arthur Ribeiro
--        Felipe Vieira
--        Jeysibel Dantas
--        Paulo Victor
--Euphoric Checkers
--

include utils.ex
include takes.ex
include std/math.e

-- Verify if a white move is valid (Normal Piece)
export function isBlackValidMove(integer currentLine,integer currentCell, integer nextLine, integer nextCell)
--?currentLine
--?currentCell
--?nextLine
--?nextCell
  if nextLine=currentLine+1 then    
    if currentCell=1 then      
      if nextCell=currentCell+1 then return TRUE else return FALSE end if
    end if
    if currentCell=8 then
      if nextCell=currentCell-1 then return TRUE else return FALSE end if
    end if
    if currentCell>1 and currentCell<8 then      
      if nextCell=currentCell+1 or nextCell=currentCell-1 then return TRUE else return FALSE end if
    end if
  else
    return FALSE
  end if

end function


-- Verify if a black move is valid (Normal Piece)
export function isWhiteValidMove(integer currentLine,integer currentCell, integer nextLine, integer nextCell)
  if nextLine=currentLine-1 then    
    if currentCell=1 then      
      if nextCell=currentCell+1 then return TRUE else return FALSE end if
    end if
    if currentCell=8 then
      if nextCell=currentCell-1 then return TRUE else return FALSE end if
    end if
    if currentCell>1 and currentCell<8 then      
      if nextCell=currentCell+1 or nextCell=currentCell-1 then return TRUE else return FALSE end if
    end if
  else
    return FALSE
  end if

end function

export function isInSameDiagonal(sequence source, sequence destiny)
    return abs(source[1]-destiny[1])=abs(source[2]-destiny[2])
end function

export function isValidKingMove(atom player, sequence moveArgs)

    atom lineStart = moveArgs[1]
    atom columnStart = moveArgs[2]
    atom lineStop = moveArgs[3]
    atom columnStop = moveArgs[4]
    --?lineStart
    --?columnStart
    --?lineStop
    --?columnStop
    
    if not isInSameDiagonal({lineStart,columnStart},{lineStop,columnStop}) then     
        return FALSE
    end if

        
    atom sourceData = board[lineStart][columnStart]
    atom destData = board[lineStop][columnStop]
    
    sequence piecesBetween = getDiagonalElementsBetween({lineStart,columnStart},{lineStop,columnStop})
    
    -- Verify if there's any piece of the same color along the move

    if (equal(board[lineStart][columnStart],WHITE_KING)) then
        for i=1 to length(piecesBetween) do
            if equal(piecesBetween[i],WHITE) then               
                return FALSE
            end if
        end for
    end if
    
    if (equal(board[lineStart][columnStart],BLACK_KING)) then
        for i=1 to length(piecesBetween) do
            if equal(piecesBetween[i],BLACK) then                               
                return FALSE
            end if
        end for
    end if
    
    
    -- Verify if there's opponent's consecutive pieces along the move
    
    if (equal(board[lineStart][columnStart],WHITE_KING)) then
        for i=1 to length(piecesBetween)-1 do
            if piecesBetween[i]=BLACK and piecesBetween[i+1]=BLACK then         
                return FALSE
            end if
        end for
    end if
    
    if (equal(board[lineStart][columnStart],BLACK_KING)) then
        for i=1 to length(piecesBetween)-1 do
            if piecesBetween[i]=WHITE and piecesBetween[i+1]=WHITE then         
                return FALSE
            end if
        end for
    end if
    return TRUE
end function


export function verifyPieceExistence(integer line, integer cell)
    return not board[line][cell]=0
end function

export function verifyPossibleMoves(sequence board, atom player)

  sequence possibleMoves = {}

  for i=1 to length(board) do
    for j=1 to length(board[i]) do
      if board[i][j]=player then
        possibleMoves &=verifyEmptyPlacesForward(board,player,i,j)
      end if
    end for
  end for

--puts(1,"Possible Moves: ")
--? possibleMoves

  return possibleMoves



end function

export function verifyEmptyPlacesForward(sequence board,atom player, atom line, atom column)
  sequence possibleMoves = {}
  --test white moves
  if equal(player,WHITE) then
    --excludes right check for right border column
    if not equal(column,9) and not equal(column,8) and not equal(line,0) and not equal(line,1) then
      --test right
      if equal(board[line-1][column +1], 0) then 
            possibleMoves = append(possibleMoves,{line,column,line-1,column+1})
      end if
    end if
    --excludes left check for left border column
    if not equal(column,0) and not equal(column,1) and not equal(line,0) and not equal(line,1) then
      --test left
      if equal(board[line-1][column -1], 0) then 
             possibleMoves = append(possibleMoves,{line,column,line-1,column-1})
      end if
    end if
  end if
  --test black moves
  if equal(player,BLACK) then
    --excludes right check for right border column
    if not equal(column,0) and not equal(column,1) and not equal(line,8) and not equal(line,9) then    
      --test right
      if equal(board[line+1][column -1], 0) then 
             possibleMoves = append(possibleMoves,{line,column,line+1,column-1})
      end if
    end if
    --excludes left check for left border column
    if not equal(column,8) and not equal(column,9) and not equal(line,8) and not equal(line,9)then    
      --test left
      if equal(board[line+1][column+1], 0) then 
             possibleMoves = append(possibleMoves,{line,column,line+1,column+1})
      end if
    end if
  end if

return possibleMoves

end function



export function performMove(atom player, sequence moveArgs)
    atom lineStart = moveArgs[1]
    atom columnStart = moveArgs[2]
    atom lineStop = moveArgs[3]
    atom columnStop = moveArgs[4]
    --?lineStart
    --?columnStart
    --?lineStop
    --?columnStop
    atom sourceData = board[lineStart][columnStart]
    atom destData = board[lineStop][columnStop]

    if not equal(player,sourceData) and not equal(0,destData) then
      return FALSE
    else
      board[lineStop][columnStop] = sourceData
      board[lineStart][columnStart] = destData
    end if
return TRUE

end function


export function performKingMove(atom player, sequence moveArgs)
    atom lineStart = moveArgs[1]
    atom columnStart = moveArgs[2]
    atom lineStop = moveArgs[3]
    atom columnStop = moveArgs[4]
    --?lineStart
    --?columnStart
    --?lineStop
    --?columnStop
    
    atom source = board[lineStart][columnStart]
    atom next = board[lineStop][columnStop]
    
    if isValidKingMove(player,moveArgs) then        
        if lineStart>lineStop then
            
            if columnStart>columnStop then          
            for i=1 to abs(lineStart-lineStop) do
                 board[lineStart+i][columnStart-i]=0
            end for 
            end if
            
            if columnStart<columnStop then
                for i=1 to abs(lineStart-lineStop) do
                 board[lineStart-i][columnStart+i]=0
                end for 
            end if
            
                        
        else
            
            if columnStart>columnStop then      
            for i=1 to abs(lineStart-lineStop) do
                board[lineStart+i][columnStart-i]=0
            end for
            end if
            
            if columnStart<columnStop then      
            for i=1 to abs(lineStart-lineStop) do
                board[lineStart+i][columnStart+i]=0
            end for
            end if
        end if
            
            
        
        board[lineStop][columnStop]= source
        board[lineStart][columnStart]=0
        
        return TRUE
    end if

    return FALSE
    
end function 

export procedure verifyAndCreateKings() 
    for i=1 to length(board[WHITE_ORIGIN]) do
        if board[WHITE_ORIGIN][i]=2 then
            board[WHITE_ORIGIN][i]=BLACK_KING
        end if
    end for
    
    for i=1 to length(board[BLACK_ORIGIN]) do
        if board[BLACK_ORIGIN][i]=1 then
            board[BLACK_ORIGIN][i]=WHITE_KING
        end if
    end for
    
    --?board
    
end procedure





